/**
* ...
* @author Exey Panteleev
*/
package  {
	import flash.events.KeyboardEvent;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.view.BasicView;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import org.papervision3d.view.stats.StatsView;
	
	
	import fl.accessibility.ListAccImpl;
	import fl.controls.CheckBox;
	import fl.controls.Button;
	import fl.controls.TextArea;
	import flash.display.Stage;
	import flash.geom.Rectangle;
	import fl.controls.List;
	import fl.data.DataProvider;
	import fl.controls.List;
	import fl.events.ListEvent;
	import flash.text.TextField;
	import fl.controls.TextArea;
	import fl.controls.TextInput;
	
	/**
	* ...
	* @author Default
	*/
	[ SWF( backgroundColor = '#000000', width = '600', height = '400', frameRate='60' ) ]
	public class LsystemMorph extends BasicView {
		
		private var isDragging:Boolean = false;
		private var stats:StatsView; 
		
		private var ground:Plane;
		private var plant:Plant;
		private var testSphere:Sphere = new Sphere(new ColorMaterial(0xff0000), 200);
		private var counter:int = 0;
		
		public var marker:DisplayObject3D = new DisplayObject3D();
		
		
		public var LSys:LSystem;

		
		public function LsystemMorph() {
			super(600, 400, false, false, "CAMERA3D");
			initControls();
			preparePv3d();
			
			createMaterials();
			createObjects();
			addListeners();
			startRendering();
		}
		
		public function preparePv3d():void {
			camera.y = 600;
			camera.zoom = 4;
			stats = new StatsView(renderer);
			stage.addChild(stats);
		}
		public function createMaterials():void {
			
		}
		public function createObjects():void {
			marker.y = -400;
			marker.pitch(270);
			
			ground = new Plane (new ColorMaterial(0xDCC0A8), 1000, 1000, 5, 5);
			ground.rotationX = -90;
			ground.y = -400;
			scene.addChild(ground);
			var commands:String = "X:F-[[&X]+<<<X]+F[>>>+!F-X]\nF:FF";
			LSys = new LSystem(22.5, 5, "X");
			LSys.ratio = 0.94;
			LSys.branchGrowingTime = 0.01;
			LSys.size = 1;
			var ar:Array = commands.split("\r");
			for(var i:int=0;i<ar.length;i++)
				LSys.rules.push(Rule.createRule(ar[i]));
			trace("rules: "+LSys.rules.length)
			marker.x = 0;
			marker.y = -400;
			marker.z = 0;
			LSys.DrawSystem(LSys.GetCommand(), 0 , marker, 1000000, 50);
			plant = new Plant( LSys );
			plant.growTrunkBranch(0); // start Growing
			scene.addChild(plant);
			
		}
		
		public function createPlant() {
			LSys = new LSystem(m_Angle.value, int(m_Iterations.value),m_Axiom.text);
			LSys.ratio = m_Ratio.value;
			LSys.branchGrowingTime = m_Time.value;
			LSys.size = m_Thickness.value;
			var ar:Array = commands.text.split("\r");
			for(var i=0;i<ar.length;i++)
				LSys.rules.push(Rule.createRule(ar[i]));
				
			var marker:DisplayObject3D = new DisplayObject3D();
			marker.x = 0;
			marker.y = -400;
			marker.z = 0;
			marker.pitch(270);
			LSys.DrawSystem(LSys.GetCommand(), 0 , marker, 1000000, m_Length.value);
			plant = new Plant( LSys );
			plant.time = m_Time.value;
			plant.growTrunkBranch(0); // start Growing
			scene.addChild(plant);
			
		}

		public function addListeners():void {
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onPressHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
			//stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
			
			
		}
		override protected function onRenderTick(event:Event=null):void
		{
			if(plant){
				plant.draw( );
			}
			rotateCamera();
			super.onRenderTick(event);
		}
		
		
		private function deletePlant() {
			if (plant) {
				//preventing memory leeks
				plant.containerForDrawing.material.unregisterObject(plant.containerForDrawing); // -25 kb
				plant.containerForDrawing.material.destroy(); // -15 kb
				plant.removeChild(plant.containerForDrawing); // -5kb
				scene.removeChild(plant);
			}
		}
		
		private function rotateCamera():void{
			if(isDragging){
				var x:Number = (stage.mouseX - stage.stageWidth/2) / 4;
				camera.moveLeft(x);
				var y:Number = (stage.mouseY - stage.stageHeight/2) / 6;
				camera.moveDown(y);
				if (camera.y > 1000 || camera.y < -200) camera.moveDown(-y);
			}
		}
		
		public function initControls() {
			var dp:DataProvider = new DataProvider();
			var i:uint;
			m_Samples.removeAll();
			removeChild(m_Samples);
			trace(m_Samples.length);
			for(i=0; i<Structures.Sets.length; i++) {
				dp.addItem({label:Structures.Sets[i].title});
			
			}
			var s:List = new List();
		
			s.dataProvider = dp;
			addChild(s);
			s.x = m_Samples.x;
			s.y = m_Samples.y;
			s.width = m_Samples.width;
			s.height = m_Samples.height;
			
			s.addEventListener(ListEvent.ITEM_CLICK, sampleClick);
			
			submit.addEventListener(MouseEvent.CLICK, submitted);
		}
		
		public function submitted(e:MouseEvent){
			deletePlant();
			createPlant();
		}
		public function sampleClick(e:ListEvent){
			var tmp:Object = Structures.Sets[e.rowIndex];
			m_Length.value = tmp.length;
			m_Angle.value = tmp.angle;
			//m_StartAngle.value = tmp.startAngle;
			m_Iterations.value = tmp.iterations;
			m_Axiom.text = tmp.axiom;
			commands.text = tmp.rules;
			m_Ratio.value = tmp.ratio;
			
			m_Thickness.value = tmp.thickness;
			
			submitted(null);
			//reset();
		}
		
		public function onPressHandler(event:MouseEvent):void {
			isDragging = true;
		}
		public function onMouseUpHandler(event:MouseEvent):void {
			isDragging = false;
		}

		private function isChar(code:Number, str:String):Boolean{
			if(code == str.charCodeAt())
				return true;
			return false;
		}
	}
}